<?php
Class Product_model extends CI_Model
{
		
	// we will store the group discount formula here
	// and apply it to product prices as they are fetched 
	var $group_discount_formula = false;
	
	function __construct()
	{
		parent::__construct();
		
		// check for possible group discount 
		$customer = $this->session->userdata('customer');
		if(isset($customer['group_discount_formula'])) 
		{
			$this->group_discount_formula = $customer['group_discount_formula'];
		}
	}
	
	function product_autocomplete($name, $limit)
	{
		return	$this->db->like('name', $name)->get('products', $limit)->result();
	}
	
	function products($data=array(), $return_count=false)
	{
		
		if(empty($data))
		{
			//if nothing is provided return the whole shabang
			$this->get_all_products();
		}
		else
		{
			//grab the limit
			if(!empty($data['rows']))
			{
				$this->db->limit($data['rows']);
			}
			
			//grab the offset
			if(!empty($data['page']))
			{
				$this->db->offset($data['page']);
			}
			
			//do we order by something other than category_id?
			if(!empty($data['order_by']))
			{
				//if we have an order_by then we must have a direction otherwise KABOOM
				$this->db->order_by($data['order_by'], $data['sort_order']);
			}
			
			//do we have a search submitted?
			if(!empty($data['term']))
			{
				$search	= json_decode($data['term']);
				//if we are searching dig through some basic fields
				if(!empty($search->term))
				{
					$this->db->like('name', $search->term);
					$this->db->or_like('description', $search->term);
					$this->db->or_like('excerpt', $search->term);
					$this->db->or_like('sku', $search->term);
				}
				
				if(!empty($search->category_id))
				{
					//lets do some joins to get the proper category products
					$this->db->join('category_products', 'category_products.product_id=products.id', 'right');
					$this->db->where('category_products.category_id', $search->category_id);
					$this->db->order_by('sequence', 'ASC');
				}
			}
			
			if($return_count)
			{
				return $this->db->count_all_results('products');
			}
			else
			{
				$out=$this->db->get('products')->result();
				foreach ($out as &$row){
					$query	= $this->db->get_where('products_photo', array('product_id'=>$row->id))->row();
					if($query)
					{
						if(!trim($row->images))$row->images=$query->link_photo;
						$row->photos=$this->db->get_where('products_photo', array('product_id'=>$row->id))->result();
					}
				}
				
				return $out;
			}
			
		}
	}
	
	function get_all_products()
	{
		//sort by alphabetically by default
		$this->db->order_by('name', 'ASC');
		$result	= $this->db->get('products');
		//apply group discount
		$return = $result->result();
		if($this->group_discount_formula) 
		{
			foreach($return as &$product) {
				eval('$product->price=$product->price'.$this->group_discount_formula.';');
			}
		}
		return $return;
	}
	
	function get_products($category_id = false, $limit = false, $offset = false, $by=false, $sort=false)
	{
		//if we are provided a category_id, then get products according to category
		if ($category_id)
		{

			$ids[]=$category_id;
			$result	= $this->db->select('id')->from('categories')->where('id',$category_id)->or_where('parent_id',$category_id)->get();
			foreach ($result->result() as $cat)
			if($cat->id!=$category_id) $ids[]=$cat->id;
			
			$this->db->select('category_products.*, LEAST(IFNULL(NULLIF(saleprice, 0), price), price) as sort_price', false)->
			from('category_products')->
			join('products', 'category_products.product_id=products.id')->
			where(array('enabled'=>1))->where_in('category_id',$ids);
			$this->db->order_by($by, $sort);
			
			$result	= $this->db->limit($limit)->offset($offset)->get()->result();

			$contents	= array();
			foreach ($result as $product){
				$contents[]	= $this->get_product($product->product_id);
			}

			return $contents;
		}
		else
		{
			//sort by alphabetically by default
			$this->db->order_by('name', 'ASC');
			$result	= $this->db->get('products');
			//apply group discount
			$return = $result->result();
			if($this->group_discount_formula) 
			{
				foreach($return as &$product) {
					eval('$product->price=$product->price'.$this->group_discount_formula.';');
				}
			}
			return $return;
		}
	}
	
	function count_all_products()
	{
		return $this->db->count_all_results('products');
	}
	
	function count_products($id)
	{
		$ids[]=$id;
		$result	= $this->db->select('id')->from('categories')->where('id',$id)->or_where('parent_id',$id)->get();
		foreach ($result->result() as $cat)
			if($cat->id!=$id) $ids[]=$cat->id;
		return $this->db->select('product_id')->from('category_products')->join('products', 'category_products.product_id=products.id')->where_in('category_id',$ids)->where('enabled',1)->count_all_results();
	}

	function get_product($id, $related=true)
	{
		$result	= $this->db->get_where('products', array('id'=>$id))->row();
		if(!$result)
		{
			return false;
		}

		$related	= json_decode($result->related_products);
		
		if(!empty($related))
		{
			//build the where
			$where = false;
			foreach($related as $r)
			{
				if(!$where)
				{
					$this->db->where('id', $r);
				}
				else
				{
					$this->db->or_where('id', $r);
				}
				$where = true;
			}
		
			$result->related_products	= $this->db->get('products')->result();
		}
		else
		{
			$result->related_products	= array();
		}
		$result->categories			= $this->get_product_categories($result->id);
		$result->primary_photo=$result->images;
		// group discount?
		if($this->group_discount_formula) 
		{
			eval('$result->price=$result->price'.$this->group_discount_formula.';');
		}
		$query	= $this->db->get_where('products_photo', array('product_id'=>$id))->row();
		
		if(!$query)
		{
			$result->images=$result->primary_photo='';
		}else{
			$result->images=$this->get_product_id_images($id,true);
		}
		
		$result->option	= $this->db->get_where('option_values', array('product_id'=>$id))->result();
		
		
		return $result;
	}

	function get_product_categories($id)
	{
		return $this->db->where('product_id', $id)->join('categories', 'category_id = categories.id')->get('category_products')->result();
	}

	function get_slug($id)
	{
		return $this->db->get_where('products', array('id'=>$id))->row()->slug;
	}

	function check_slug($str, $id=false)
	{
		$this->db->select('slug');
		$this->db->from('products');
		$this->db->where('slug', $str);
		if ($id)
		{
			$this->db->where('id !=', $id);
		}
		$count = $this->db->count_all_results();

		if ($count > 0)
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	function save($product, $options=false, $categories=false,$images=false)
	{
		if ($product['id'])
		{
			$this->db->where('id', $product['id']);
			$this->db->update('products', $product);

			$id	= $product['id'];
		}
		else
		{
			$this->db->insert('products', $product);
			$id	= $this->db->insert_id();
		}

		//loop through the product options and add them to the db
		if($options !== false)
		{
			$obj =& get_instance();
			$obj->load->model('Option_model');
			foreach ($options as &$option) $option['product_id']=$id;

			// wipe the slate
			$obj->Option_model->clear_options($id);
			$obj->Option_model->save_option($options);
			
		}
		if(is_array($images) and !empty($images))
		{

			if($product['id'])
			{
				//get all the categories that the product is in
				$imgs	= $this->get_product_id_images($id);
				
				//generate cat_id array
				$ids	= array();
				foreach($imgs as $c)
				{
					$ids[]	= $c;
				}

				//eliminate categories that products are no longer in
				foreach($ids as $c)
				{
					if(!in_array($c, $imgs))
					{
						$this->db->delete('products_photo', array('product_id'=>$product['id'],'id'=>$c));
					}
				}
				
				//add products to new categories
				foreach($images as $index=>$c)
				{
					if(!in_array($index, $ids))
					{
						$this->db->insert('products_photo', array('product_id'=>$product['id'],'link_photo'=>$c));
					}
				}
			}
			else
			{

				//new product add them all
				foreach($images as $c)
				{
					$this->db->insert('products_photo', array('product_id'=>$id,'link_photo'=>$c));
				}
			}

		}
		
		if($categories !== false)
		{
			if($product['id'])
			{
				//get all the categories that the product is in
				$cats	= $this->get_product_categories($id);
				
				//generate cat_id array
				$ids	= array();
				foreach($cats as $c)
				{
					$ids[]	= $c->id;
				}

				//eliminate categories that products are no longer in
				foreach($ids as $c)
				{
					if(!in_array($c, $categories))
					{
						$this->db->delete('category_products', array('product_id'=>$id,'category_id'=>$c));
					}
				}
				
				//add products to new categories
				foreach($categories as $c)
				{
					if(!in_array($c, $ids))
					{
						$this->db->insert('category_products', array('product_id'=>$id,'category_id'=>$c));
					}
				}
			}
			else
			{
				//new product add them all
				foreach($categories as $c)
				{
					$this->db->insert('category_products', array('product_id'=>$id,'category_id'=>$c));
				}
			}
		}
		
		//return the product id
		return $id;
	}
	function get_product_id_images($product_id,$full=false){
		$query	= $this->db->get_where('products_photo', array('product_id'=>$product_id));
		$ids=array();
		foreach ($query->result() as $photo)
			if($full)
				$ids[$photo->id]=$photo->link_photo;
			else $ids[]=$photo->id;
		return $ids;
	}
	
	function delete_product($id)
	{
		// delete product 
		$this->db->where('id', $id);
		$this->db->delete('products');

		//delete references in the product to category table
		$this->db->where('product_id', $id);
		$this->db->delete('category_products');
		
		// delete coupon reference
		$this->db->where('product_id', $id);
		$this->db->delete('coupons_products');
		
		//delete option
		$this->db->delete('option_values', array('product_id' => $id));
		//delete photo
		$images=$this->get_product_id_images($id,true);
		
		$folder=dirname(dirname(__DIR__));
		foreach ($images as $image){
			unlink($folder.'/images/'.$image);
			unlink($folder.'/images/thumbnails/'.$image);
		}
		$this->db->delete('products_photo', array('product_id' => $id));

	}

	function add_product_to_category($product_id, $optionlist_id, $sequence)
	{
		$this->db->insert('product_categories', array('product_id'=>$product_id, 'category_id'=>$category_id, 'sequence'=>$sequence));
	}

	function search_products($term, $limit=false, $offset=false, $by=false, $sort=false)
	{
		$results		= array();
		
		$this->db->select('*, LEAST(IFNULL(NULLIF(saleprice, 0), price), price) as sort_price', false);
		//this one counts the total number for our pagination
		$this->db->where('enabled', 1);
		$this->db->where('(name LIKE "%'.$term.'%" OR description LIKE "%'.$term.'%" OR excerpt LIKE "%'.$term.'%" OR sku LIKE "%'.$term.'%")');
		$results['count']	= $this->db->count_all_results('products');


		$this->db->select('*, LEAST(IFNULL(NULLIF(saleprice, 0), price), price) as sort_price,images as primary_photo', false);
		//this one gets just the ones we need.
		$this->db->where('enabled', 1);
		$this->db->where('(name LIKE "%'.$term.'%" OR description LIKE "%'.$term.'%" OR excerpt LIKE "%'.$term.'%" OR sku LIKE "%'.$term.'%")');
		
		if($by && $sort)
		{
			$this->db->order_by($by, $sort);
		}
		
		$results['products']	= $this->db->get('products', $limit, $offset)->result();
		foreach ($results['products'] as &$product){
			$category_product = $this->db->get_where('category_products', array('product_id' => $product->id),1)->row();
			if(isset($category_product->category_id)){
				$category= $this->db->get_where('categories', array('id' => $category_product->category_id),1)->row();
				if(isset($category->name)){
					$product->category_name=$category->name;
					$product->category_slug[]=$category->slug;
					if($category->parent_id){
						$category_parent= $this->db->get_where('categories', array('id' => $category->parent_id),1)->row();
						$product->category_slug[]=$category_parent->slug;
						$product->category_slug=array_reverse($product->category_slug);
					}
					$product->slug=implode('/',$product->category_slug).'/'.$product->slug;
				}
			}
		}
		return $results;
	}
	function search_products_promo($limit=false, $offset=false, $by=false, $sort=false)
	{
		$results		= array();
	
		$this->db->select('*, LEAST(IFNULL(NULLIF(saleprice, 0), price), price) as sort_price', false);
		//this one counts the total number for our pagination
		$this->db->where('enabled', 1);
		$this->db->where('promotion',1);
		$results['count']	= $this->db->count_all_results('products');
	
	
		$this->db->select('*, LEAST(IFNULL(NULLIF(saleprice, 0), price), price) as sort_price,images as primary_photo', false);
		//this one gets just the ones we need.
		$this->db->where('enabled', 1);
		$this->db->where('promotion',1);
		if($by && $sort)
		{
			$this->db->order_by($by, $sort);
		}
	
		$results['products']	= $this->db->get('products', $limit, $offset)->result();
		foreach ($results['products'] as &$product){
			$category_product = $this->db->get_where('category_products', array('product_id' => $product->id),1)->row();
			if(isset($category_product->category_id)){
				$category= $this->db->get_where('categories', array('id' => $category_product->category_id),1)->row();
				if(isset($category->name)){
					$product->category_name=$category->name;
					$product->category_slug[]=$category->slug;
					if($category->parent_id){
						$category_parent= $this->db->get_where('categories', array('id' => $category->parent_id),1)->row();
						$product->category_slug[]=$category_parent->slug;
						$product->category_slug=array_reverse($product->category_slug);
					}
					$product->slug=implode('/',$product->category_slug).'/'.$product->slug;
				}
			}
		}
		return $results;
	}
	// Build a cart-ready product array
	function get_cart_ready_product($id, $quantity=false)
	{
		$product	= $this->db->get_where('products', array('id'=>$id))->row();
		
		//unset some of the additional fields we don't need to keep
		if(!$product)
		{
			return false;
		}
		
		$product->base_price	= $product->price;

		
		if ((int)$product->saleprice)
		{ 
			$product->price	= $product->saleprice;
		}
		
		
		// Some products have n/a quantity, such as downloadables
		//overwrite quantity of the product with quantity requested
		if (!$quantity || $quantity <= 0 || $product->fixed_quantity==1)
		{
			$product->quantity = 1;
		}
		else
		{
			$product->quantity = $quantity;
		}
		//adapte option price
		$options	= $this->db->order_by("unit", "ASC")->get_where('option_values', array('product_id'=>$id))->result();
		if(!empty($options)){
			foreach ($options as $option)
				$product->option[$option->unit]=$option->price;
			foreach ($options as $option)
				if($quantity>=$option->unit){
					$product->price	= $option->price;
					break;
				}
		}
		// saving memory of cart
		$product->description='';
		// attach list of associated downloadables
		//$product->file_list	= $this->Digital_Product_model->get_associations_by_product($id);
		
		return (array)$product;
	}
	function deletePhoto($product_id,$ids){
		$folder=dirname(dirname(__DIR__));
		foreach ($ids as $id){
			$photo=$this->db->get_where('products_photo', array('product_id'=>$product_id,'id'=>$id))->row();		
			unlink($folder.'/images/'.$photo->link_photo);
			unlink($folder.'/images/thumbnails/'.$photo->link_photo);
			$this->db->delete('products_photo', array('product_id' => $product_id,'id'=>$id));
			
		}
	}
	function get_Special_boxes($limit)
	{
		$this->db->order_by('id', 'RANDOM');
		$this->db->limit($limit);
		$products=$this->db->get('products');
		$out=array();
		foreach ($products->result() as $product){
			$product->category_name=$product->category_slug='';
			$category_product = $this->db->get_where('category_products', array('product_id' => $product->id),1)->row();
			if(isset($category_product->category_id)){
				$category= $this->db->get_where('categories', array('id' => $category_product->category_id),1)->row();
				if(isset($category->name)){
					$product->category_name=$category->name;
					$product->category_slug[]=$category->slug;
					if($category->parent_id){
						$category_parent= $this->db->get_where('categories', array('id' => $category->parent_id),1)->row();
						$product->category_slug[]=$category_parent->slug;
						$product->category_slug=array_reverse($product->category_slug);
					}
						
				}
			}
			
			$out[]=$product;
		}
		return $out;
	}

	function get_product_category_random($limit)
	{
		//selected random 3 category which have atless 4 products
		$this->db->select('category_id');
		$this->db->select('count(category_id) as num');
		$this->db->having('num >3');
		$this->db->order_by('id', 'RANDOM');
		$this->db->group_by("category_id");
		$this->db->limit($limit);
		$categories=$this->db->get('category_products'); 
		$out=array();
		foreach ($categories->result() as $catId){
			$category= $this->db->get_where('categories', array('id' => $catId->category_id),1)->row();
			if(isset($category->name)){
				$out[$catId->category_id]['category_name']=$category->name;
				$out[$catId->category_id]['category_slug'][]=$category->slug;
				if($category->parent_id){
					$category_parent= $this->db->get_where('categories', array('id' => $category->parent_id),1)->row();
					$out[$catId->category_id]['category_slug'][]=$category_parent->slug;
					$out[$catId->category_id]['category_slug']=array_reverse($out[$catId->category_id]['category_slug']);
				}

				$category_product = $this->db->order_by('product_id', 'RANDOM')->get_where('category_products', array('category_id' => $catId->category_id),4);
				foreach ($category_product->result() as $product){

					$out[$catId->category_id]['products'][]=self::get_product($product->product_id);
				}
			}
		}
		
		
		return $out;
	}
	
}